package cn.afterturn.easypoi.word.parse;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.util.PoiElUtil;
import cn.afterturn.easypoi.word.entity.bookmark.*;
import cn.afterturn.easypoi.word.entity.bookmark.ExportExecel.Constant;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

import static cn.afterturn.easypoi.util.PoiElUtil.END_STR;
import static cn.afterturn.easypoi.util.PoiElUtil.START_STR;
import static org.junit.Assert.assertTrue;

public class BookmarkHandleFromWordEntityToMap {
    private static SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd");
    //private WordEntityVO wordEntityVO;
    public Map<String,Object> getMap(WordEntityVO wordEntityVO) {
        Map<String, Object> map = new HashMap<>();
        if (wordEntityVO.getHeaderEntityVOS() != null) {
            wordEntityVO.getHeaderEntityVOS().forEach(headerEntity -> {
                if (headerEntity.getParagraphEntityVOS() != null) {
                    headerEntity.getParagraphEntityVOS().forEach(paragraphEntity -> {
                        if (paragraphEntity.getBookMarkEntityVOS() != null) {
                            paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                                HandleBookMark(bookMarkEntity, map);
                            });
                        }
                    });
                }
            });
        }
        if (wordEntityVO.getFootEntityVOS() != null) {
            wordEntityVO.getFootEntityVOS().forEach(footEntity -> {
                if (footEntity.getParagraphEntityVOS() != null) {
                    footEntity.getParagraphEntityVOS().forEach(paragraphEntity -> {
                        if (paragraphEntity.getBookMarkEntityVOS() != null) {
                            paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                                HandleBookMark(bookMarkEntity, map);
                            });
                        }
                    });
                }
            });
        }
        if (wordEntityVO.getParagraphEntityVOS() != null) {
            wordEntityVO.getParagraphEntityVOS().forEach(paragraphEntity -> {
                if (paragraphEntity.getBookMarkEntityVOS() != null) {
                    paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                        HandleBookMark(bookMarkEntity, map);
                    });
                }
            });
        }

        //非循环的行处理
        wordEntityVO.getTableEntityVOS().forEach(tableEntity -> {
            tableEntity.getRowEntityVOS().forEach(rowEntity -> {
                rowEntity.getCellEntityVOS().forEach(cellEntity -> {
                    if (cellEntity.getParagraphEntityVOS() != null) {//非空的处理
                        //不循环的行处理。把空的排除掉
                        if (!rowEntity.getRowFirstColumnText().contains(PoiElUtil.FOREACH)) {
                            cellEntity.getParagraphEntityVOS().forEach(paragraphEntity -> {
                                paragraphEntity.getBookMarkEntityVOS().forEach(bookMarkEntity -> {
                                    HandleBookMark(bookMarkEntity, map);
                                });
                            });
                        }
                    }
                });
            });
        });
        //循环的行处理
        wordEntityVO.getTableEntityVOS().forEach(tableEntity -> {
            tableEntity.getRowEntityVOS().forEach(rowEntity -> {
                if (rowEntity.getRowFirstColumnText().contains(PoiElUtil.FOREACH)) {
                    String key = tableEntity.getTableText().hashCode() + "#" + rowEntity.getRowIndex();
                    List<Map<String, Object>> maprowlist = getMap(rowEntity);
                    map.put(key, maprowlist);
                }
            });
        });
        return map;
    }
    private void HandleBookMark(BookMarkEntityVO bookMarkEntityVO, MultiValueEntityVO multiValueEntityVO, Map<String,Object> maplist){
        String currentText = bookMarkEntityVO.getBookmarkname().trim();
        currentText = currentText.substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR));
        if (bookMarkEntityVO.getBookmarkType().contains(Constant.NormalbookMark)) {

            maplist.put(currentText, multiValueEntityVO.getBookmarkvalue());
        }
        if (bookMarkEntityVO.getBookmarkType().contains(Constant.ComputedbookMark)) {

            if (currentText.toLowerCase().contains(Constant.NOW)) {
                maplist.put(currentText, format.format(new Date()));
            }
            //对图片的新处理方式
            if (currentText.contains(Constant.PICTURE)) {
                try {
                    ImageEntity image = ImageParse.parseImage(multiValueEntityVO.getImageValueEntityVO());
                    maplist.put(currentText.trim(), image);

                } catch (Exception ex) {

                }

            }
        }
    }
    private void HandleBookMark(BookMarkEntityVO bookMarkEntityVO, Map<String,Object> map){
        String currentText = bookMarkEntityVO.getBookmarkname().trim();
        currentText = currentText.substring(currentText.indexOf(START_STR) + 2, currentText.indexOf(END_STR));
        if (bookMarkEntityVO.getBookmarkType().contains(Constant.NormalbookMark)) {

            map.put(currentText, bookMarkEntityVO.getBookmarkvalue());
        }
        if (bookMarkEntityVO.getBookmarkType().contains(Constant.ComputedbookMark)) {

            if (currentText.toLowerCase().contains(Constant.NOW)) {
                map.put(currentText, format.format(new Date()));
            }
            //对图片的新处理方式
            if (currentText.contains(Constant.PICTURE)) {
                if(bookMarkEntityVO.getImageValueEntityVO()!=null) {
                    try {
                        ImageEntity image = ImageParse.parseImageExt(bookMarkEntityVO.getImageValueEntityVO());
                        map.put(currentText.trim(), image);
                    }catch (Exception ex){
                        map.put(currentText.trim(), ex.toString());
                    }

                }
                else
                    map.put(currentText.trim(),"");



            }
        }
    }
    //处理Header部分

    private void setAllBookMarkFromRow(RowEntityVO rowEntityVO){
        Set<BookMarkEntityVO> resultBookMarks=new HashSet<>();
        rowEntityVO.getCellEntityVOS().forEach(cellEntityVO -> {
            cellEntityVO.getParagraphEntityVOS().forEach(paragraphEntityVO -> {
                paragraphEntityVO.getBookMarkEntityVOS().forEach(bookMarkEntityVO -> {
                    resultBookMarks.add(bookMarkEntityVO);
                });
            });
        });

        rowEntityVO.setBookMarkEntityVOS(resultBookMarks);
    }
    /*
    原来的getMap有缺陷，更新一下

    * */

    public List<Map<String,Object>> getMap(RowEntityVO rowEntityVO){
        setAllBookMarkFromRow(rowEntityVO);
        int maxCount=getMultiValueSizeMax(rowEntityVO);
        List<Map<String,Object>> rowList=new ArrayList<>();
        int sequence=1;
        for(int i=1;i<=maxCount;i++){
            Map<String,Object> mapItem=new HashMap<>();
            for(BookMarkEntityVO bookMarkEntityVO:rowEntityVO.getBookMarkEntityVOS()){
                String bookmarkKey=bookMarkEntityVO.getBookmarkname();
                bookmarkKey = bookmarkKey.trim();
                bookmarkKey = bookmarkKey.substring(bookmarkKey.indexOf(START_STR) + 2, bookmarkKey.indexOf(END_STR));
                Object mapvalue="";
                MultiValueEntityVO multiValueEntityVO=getMultiValueEntityVO(bookMarkEntityVO,sequence);
                if(multiValueEntityVO!=null){
                    //对图片或bookvalue值处理
                    if (bookMarkEntityVO.getBookmarkType().contains(Constant.NormalbookMark)) {
                        mapvalue=multiValueEntityVO.getBookmarkvalue();
                    }
                    if (bookMarkEntityVO.getBookmarkType().contains(Constant.ComputedbookMark)) {
                        if (bookmarkKey.toLowerCase().contains(Constant.NOW)) {
                            mapvalue=format.format(new Date());
                        }
                        //对图片的新处理方式
                        if (bookmarkKey.contains(Constant.PICTURE)) {
                                if(multiValueEntityVO.getImageValueEntityVO()!=null) {
                                    try {
                                        ImageEntity image = ImageParse.parseImageExt(multiValueEntityVO.getImageValueEntityVO());
                                        mapvalue=image;
                                    }catch (Exception ex){
                                        mapvalue=ex.toString();
                                    }

                                }
                                else mapvalue="";
                        }
                }

            }
                mapItem.put(bookmarkKey,mapvalue);
            }
            sequence++;
            rowList.add(mapItem);
        }
        return rowList;
    }

    private MultiValueEntityVO getMultiValueEntityVO(BookMarkEntityVO bookMarkEntityVO,int sequence){
        MultiValueEntityVO multiValueEntityVO;
        Set<MultiValueEntityVO> mset=bookMarkEntityVO.getMultiValueEntityVOS()
                .stream()
                .filter(m->m.getSequence()==sequence)
                .collect(Collectors.toSet());
        //引入断言，这个集合只能有<=1个值
        assertTrue(mset.size()<=1);
        if(mset.size()>0)
        multiValueEntityVO=mset.iterator().next();
        else
            multiValueEntityVO=new MultiValueEntityVO();

        return multiValueEntityVO;
    }
    private void handle(MultiValueEntityVO multiValueEntityVO){
        String value="";
        //if(multiValueEntityVO.getSequence())
    }
    //获取循环列中Multivalue的最大值
    //解决有可能Row下面的每个单元格可能填写的循环的次数不一样。
    //针对Lamda表达式，运行外部输入参数，但是不能修改。另外排版对齐也不太好调试。所以，未来简单的功能放入到Lamda，复杂的还用for循环
    private int getMultiValueSizeMax(RowEntityVO rowEntityVO){
        int maxCount=0;
        for (CellEntityVO cellEntityVO : rowEntityVO.getCellEntityVOS()) {
            for (ParagraphEntityVO paragraphEntityVO : cellEntityVO.getParagraphEntityVOS()) {
                for (BookMarkEntityVO bookMarkEntityVO : paragraphEntityVO.getBookMarkEntityVOS()) {
                    int size=bookMarkEntityVO.getMultiValueEntityVOS().size();
                    if(maxCount<size){
                        maxCount=size;
                    }
                }
            }
        }
        return maxCount;
    }
}
